package com.dankegongyu.lib.map.baidu;

import android.content.Context;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;

/**
 * 定位工具类
 *
 * @author wpq
 * @version 1.0
 */
public class LocationService {

    private LocationClient client;
    private LocationClientOption defaultOption, customOption;

    public static LocationService neInstance(Context context) {
        return newInstance(context, 0);
    }

    /**
     * @param scanSpan 定位间隔时间，单位ms
     */
    public static LocationService newInstance(Context context, int scanSpan) {
        return new LocationService(context, scanSpan);
    }

    private LocationService(Context context, int scanSpan) {
        client = new LocationClient(context);
        client.setLocOption(getDefaultLocationClientOption(scanSpan));
    }

    /**
     * 默认的定位参数
     */
    public LocationClientOption getDefaultLocationClientOption(int scanSpan) {
        if (defaultOption == null) {
            defaultOption = new LocationClientOption();
            // 可选，设置定位模式，默认高精度
            // LocationMode.Hight_Accuracy：高精度；
            // LocationMode. Battery_Saving：低功耗；
            // LocationMode. Device_Sensors：仅使用设备；
            defaultOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);

            // 可选，设置是否使用gps，默认false
            // 使用高精度和仅用设备两种定位模式的，参数必须设置为true
            defaultOption.setOpenGps(true);

            // 可选，设置返回经纬度坐标类型，默认gcj02
            // gcj02：国测局坐标；
            // bd09ll：百度经纬度坐标；
            // bd09：百度墨卡托坐标；
            // 海外地区定位，无需设置坐标类型，统一返回wgs84类型坐标
            defaultOption.setCoorType("bd09ll");

            // 可选，设置发起定位请求的间隔，int类型，单位ms
            // 如果设置为0，则代表单次定位，即仅定位一次，默认为0
            // 如果设置非0，需设置1000ms以上才有效
            defaultOption.setScanSpan(scanSpan);

            // 可选，设置是否当GPS有效时按照1S/1次频率输出GPS结果，默认false
            defaultOption.setLocationNotify(false);

            // 可选，设置是否需要地址信息，默认不需要
            defaultOption.setIsNeedAddress(true);

            // 可选，设置是否需要设备方向结果
            defaultOption.setNeedDeviceDirect(false);

            // 可选，定位SDK内部是一个service，并放到了独立进程。
            // 设置是否在stop的时候杀死这个进程，默认（建议）不杀死，即setIgnoreKillProcess(true)
            defaultOption.setIgnoreKillProcess(true);

            // 可选，默认false，设置是否需要位置语义化结果，可以在BDLocation.getLocationDescribe里得到，结果类似于“在北京天安门附近”
            defaultOption.setIsNeedLocationDescribe(true);

            // 可选，默认false，设置是否需要POI结果，可以在BDLocation.getPoiList里得到
            defaultOption.setIsNeedLocationPoiList(true);

            // 可选，设置是否收集Crash信息，默认收集，即参数为false
            defaultOption.SetIgnoreCacheException(false);

            // 可选，默认false，设置定位时是否需要海拔信息，默认不需要，除基础定位版本都可用
            defaultOption.setIsNeedAltitude(false);
        }
        return defaultOption;
    }

    public void setScanSpan(int scanSpan) {
        if (defaultOption != null && null != client) {
            defaultOption.setScanSpan(scanSpan);
            client.setLocOption(defaultOption);
        }
    }

    public boolean setLocationOption(LocationClientOption option) {
        boolean isSuccess = false;
        if (option != null && null != client) {
            if (client.isStarted())
                client.stop();
            customOption = option;
            client.setLocOption(option);
            isSuccess = true;
        }
        return isSuccess;
    }

    public LocationClientOption getOption() {
        return customOption;
    }

    public boolean registerListener(BDAbstractLocationListener listener) {
        boolean isSuccess = false;
        if (listener != null && null != client) {
            client.registerLocationListener(listener);
            isSuccess = true;
        }
        return isSuccess;
    }

    public void unregisterListener(BDAbstractLocationListener listener) {
        if (listener != null && null != client) {
            client.unRegisterLocationListener(listener);
        }
    }

    public void startLocation() {
        if (client != null && null != client) {
            if (client.isStarted()) {
                client.stop();
            }
            client.start();
        }
    }

    public void stopLocation() {
        if (client != null && client.isStarted()) {
            client.stop();
        }
    }

    public boolean requestHotSpotState() {
        return client.requestHotSpotState();
    }

    /**
     * 重启定位
     * http://lbsyun.baidu.com/index.php?title=android-locsdk/guide/addition-func/android7-notice
     */
    public void restart() {
        if (client != null) {
            client.restart();
        }
    }

    /**
     * 如果开发者想按照自己逻辑请求定位，
     * 可以在start()之后按照自己的逻辑请求LocationClient.requestLocation()函数，
     * 会主动触发定位SDK内部定位逻辑，等待定位回调即可
     * http://lbsyun.baidu.com/index.php?title=android-locsdk/guide/get-location/latlng
     */
    public void requestLocation() {
        if (client != null) {
            client.requestLocation();
        }
    }
}
